<?php



namespace app\common\controller;


use app\admin\model\Area;
use app\admin\model\Hospital;
use app\admin\model\School;
use app\admin\model\Student as StudentModel;
use app\common\model\Ent;
use app\common\model\Eyes;
use app\common\model\Fluoroscopy;
use app\common\model\Liver;
use app\common\model\Medicine;
use app\common\model\Stomatology;
use app\common\model\Surgery;
use auth\Auth;
use CodeItNow\BarcodeBundle\Utils\BarcodeGenerator;
use office\Excel;
use think\Db;
use think\facade\Config;
use think\facade\View;
use think\helper\Str;

class BaseAdmin extends Base
{

    protected $auth_uid;    //后台管理员登录id
    protected $check_login = true;

    protected $model = null;
    protected $searchField = [];    //搜索字段

    protected $order_id = 'id';    //排序字段
    protected $order_type = 'desc';    //排序方式

    public function initialize(){
        if ($this->check_login){
            $this->checkLogin();
        }
        $this->checkAuth();
    }

    /**
     * 通用首页
     * @return array|string
     * @throws \Exception
     */
    public function index(){
        if ($this->request->isAjax()){
            //获取搜索条件
            $data =$this->request->except(['page'],'get');
            $list = $this->model->withSearch($this->searchFields($data),$this->searchData($data))
                ->order($this->order_id,$this->order_type)
                ->paginate($data['limit'], false);
            //搜索器搜索，获取模型自定义的字段
            if (count($this->searchField)>0){
                $data_list = [];
                //是否存在扩展，返回列表需要额外添加的字段
                if (method_exists($this,$this->request->action().'Field')){
                    $action = $this->request->action().'Field';
                }
                foreach ($list as $k=>$v){
                    $data_list[$k] = $v;
                    //如果在控制器定义，需要获取，模型自定义的获取器字段，循环获取$searchField = ['recharge_sum','shop_count'];
                    foreach ($this->searchField as $model=>$field){
                        //如果当前获取的字段是关联模型的其他字段如：$searchField = ['user'=>['name'=>'username','phone'=>'phone']]
                        if (is_array($field)) {
                            foreach ($field as $modelField=>$listField){
                                try {
                                    if (is_int($modelField)) {
                                        $data_list[$k][$listField] = $v->$model->$listField;
                                    }else{
                                        $data_list[$k][$listField]  = $v->$model->$modelField;
                                    }
                                }catch (\Exception $e){
                                    $data_list[$k][$listField] = '-';
                                }
                            }
                        }else{
                            $data_list[$k][$field] = $v->$field;
                        }
                    }
                    //调用扩展方法
                    if (isset($action)){
                        $this->$action($data_list,$k,$v,$data);
                    }
                }
            }else{
                $data_list = $list->getCollection();
            }
            return $this->tableJson($data_list,$list->total(),$this->ClosureAssign($data));
        }
        $this->ClosureAssign();
        return $this->fetch();
    }

    /**
     * 用于通用curd的扩展数据
     * 增加切片点的
     * @param $data
     * @return void|array
     */
    protected function ClosureAssign($data=false){
        //是否存在当前方法的，模板变量设置方法：indexAssign
        $action = $this->request->action().'Assign';
        if (method_exists($this,$action)){
            if ($data){
                $extra =  $this->$action($data);
                return $extra?:[];
            }else {
                $this->$action($data);
            }
        }
    }

    /**
     * 通用添加编辑
     * @return array|string
     * @throws \Exception
     */
    public function edit(){
        if ($this->request->isAjax()){
            $data = $this->request->param();
            $scene = empty($data['id'])?'add':'edit';
            //获取当前模型的名称
            $name = '\\app\\admin\\service\\'.$this->model->getName().'Service';
            return json($name::store($data,$scene));
        }
        //编辑的数据查询
        $id = $this->request->get('id');
        if ($id){
            $list = $this->model->find($id);
            $this->assign('list', $list);
        }
        //是否存在当前方法的，模板变量设置方法：indexAssign
        $this->ClosureAssign();
        return $this->fetch();
    }

    /**
     * 通用回收站
     * @return array|string
     * @throws \Exception
     */
    public function recycle(){
        if ($this->request->isAjax()){
            //获取搜索条件
            $data =$this->request->except(['page'],'get');
            $list = $this->model->onlyTrashed()->withSearch($this->searchFields($data),$this->searchData($data))
                ->order('id','desc')
                ->paginate($data['limit'], false);
            //搜索器搜索模型自定义的字段
            if (count($this->searchField)>0){
                $data_list = [];
                foreach ($list as $k=>$v){
                    $data_list[$k] = $v;
                    foreach ($this->searchField as $field){
                        $data_list[$k][$field] = $v->$field;
                    }
                }
                return $this->tableJson($data_list,$list->total());
            }else{
                return $this->tableJson($list->getCollection(),$list->total());
            }
        }
        //是否存在当前方法的，模板变量设置方法：indexAssign
        $action = $this->request->action().'Assign';
        if (method_exists($this,$action)){
            $this->$action();
        }
        return $this->fetch();
    }

    /**
     * 通用软删除
     */
    public function remove(){
        if ($this->request->isAjax()){
            $ids = $this->request->param('ids');
            $this->model->destroy($ids);
            $this->success('删除成功');
        }else{
            $this->error('非法请求');
        }
    }

    /**
     * 通用彻底删除
     */
    public function delete()
    {
        if ($this->request->isAjax()) {
            $ids = $this->request->param('ids');
            $this->model->destroy($ids, true);
            $this->success('删除成功');
        } else {
            $this->error('非法请求');
        }
    }

    /**
     * 恢复删除
     */
    public function recovery(){
        if ($this->request->isAjax()){
            $ids = $this->request->param('ids');
            $this->model->onlyTrashed()->whereIn('id',$ids)->select()->each(function($item){
                $item->restore();
            });
            $this->success('恢复成功');
        }else{
            $this->error('非法请求');
        }
    }

    /**
     * 通用更改状态
     * @return void
     */
    public function change(){
        if ($this->request->isAjax()){
            $id = $this->request->param('id');
            $state = $this->request->param('state');
            $res = $this->model->where('id',$id)->update(['state'=>$state]);
            if ($res){
                $this->success('操作成功');
            }else{
                $this->error('操作失败');
            }
        }else{
            $this->error('非法请求');
        }
    }


    /**
     * 权限登录检查
     * @param null $action
     * @param null $controller
     * @param null $module
     * @param array $route
     * @throws \Exception
     */
    protected function checkAuth($action = null,$controller = null,$module = null,array $route = []){
        if($module === null) $module = app('http')->getName();
        if($controller === null) $controller = $this->request->controller();
        if($action === null) $action = $this->request->action();

        //拼接路由
        $url = Str::lower($module.'/'.$controller.'/'.$action);

        //权限监测
        $auth = Auth::instance();
        $config = Config::get('login_admin');

        //无需认证模块
        $modules = explode(',',$config['not_auth_module']);
        $check = in_array(Str::lower($module.'/'.$controller),$modules);

        //是否登录否则人让用户登录
        $this->auth_uid = session($config['auth_uid']);
        if (!$this->auth_uid&&!$check){
            $this->redirect(url($config['user_auth_gateway']));
        }

        if(!$check&&!$auth->check($url, $this->auth_uid)){
            if($this->request->isAjax()){
                $this->error('对不起您没有该操作权限!');
            }else{
                echo $this->fetch('template@layout/access_denied');die;
            }
        }

        //后台操作日志
        admin_log($this->auth_uid?:0);
    }

    /**
     * 是否登录否则跳转登录页面
     */
    protected function checkLogin(){
        $config = Config::get('login_admin');
        $auth_uid = session($config['auth_uid']);
        if (!$auth_uid){
            if ($this->request->isAjax()) {
                die("<script language='JavaScript'>location.href=".url($config['user_auth_gateway'])."</script>");
            }else {
                $this->redirect(url($config['user_auth_gateway']));
            }
        }
        return  $auth_uid;
    }


    /**
     * 模板变量赋值
     * @param $name
     * @param null $value
     */
    protected function assign($name, $value = null){
        View::assign($name,$value);
    }

    /**
     * 解析和获取模板内容 用于输出
     * @param string $template
     * @param array $vars
     * @return string
     * @throws \Exception
     */
    protected function fetch(string $template = '', array $vars = []){
        return View::fetch($template, $vars);
    }


    /**
     * 返回表格数据
     * @param $data
     * @param $total
     * @return array
     */
    protected function tableJson($data, $total,$extra = [])
    {
        $json = [
            'code' => 0,
            'msg' => '',
            'data' => $data,
        ];
        if ($total) {
            $json = array_merge($json, ['count' => $total]);
        }
        if ($extra) {
            $json = array_merge($json, $extra);
        }
        return $json;
    }


    /**
     * 配合withSearch搜索器使用
     * @param $data
     * @return array
     */
    protected function searchFields($data){
        unset($data['limit']);
        $data = array_keys($data);
        return $data;
    }

    /**
     * 配合withSearch搜索器使用
     * @param $data
     * @return array
     */
    protected function searchData($data){
        unset($data['limit']);
        return $data;
    }


}
